Add D109 support for newer Garmins.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Thu, 14 Nov 2002 07:17:24 +0000 (07:17 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Thu, 14 Nov 2002 07:17:24 +0000 (07:17 +0000)
   (I am amused by neither Jeeps handling of this nor Garmins gratituously
incompatible protocol design ...)

gpsbabel/guibabel
gpsbabel/jeeps/gpsapp.c
gpsbabel/jeeps/gpsinput.c
gpsbabel/jeeps/gpsprot.h

index ceee62f1c81d6f8984707453bdaae04a9c6f4a90..7aec69a9695f17f51624d42081b7e6b133aff1dc 100755 (executable)
@@ -24,6 +24,8 @@ proc showCmd w {
        set cmd [concat $cmd "-s"]
   }
  set cmd [concat $cmd  "-o $ftypewrite -F $ofile"]
+# exec $cmd
  tk_messageBox -icon info -message  $cmd
 }
 
index 9021dc3deeeb042fac14b9a37f87d0cf4a3915b6..4a02b4d6e7de0b2ad7e6e7c87842f597935f00e5 100644 (file)
@@ -48,6 +48,7 @@ static void   GPS_D105_Get(GPS_PWay *way, UC *s);
 static void   GPS_D106_Get(GPS_PWay *way, UC *s);
 static void   GPS_D107_Get(GPS_PWay *way, UC *s);
 static void   GPS_D108_Get(GPS_PWay *way, UC *s);
+static void   GPS_D109_Get(GPS_PWay *way, UC *s);
 static void   GPS_D150_Get(GPS_PWay *way, UC *s);
 static void   GPS_D151_Get(GPS_PWay *way, UC *s);
 static void   GPS_D152_Get(GPS_PWay *way, UC *s);
@@ -63,6 +64,7 @@ static void   GPS_D105_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D106_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D107_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D108_Send(UC *data, GPS_PWay way, int32 *len);
+static void   GPS_D109_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D150_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D151_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D152_Send(UC *data, GPS_PWay way, int32 *len);
@@ -261,8 +263,12 @@ static void GPS_A001(GPS_PPacket packet)
     
     for(i=0;i<entries;++i,p+=3)
     {
+       char pb[256];
        tag = *p;
        data = GPS_Util_Get_Short(p+1);
+
+       snprintf(pb, sizeof(pb), "Capability '%c'.  Type %d", tag, data);
+       GPS_User(pb);
        
        /* Only one type of P[hysical] so far */
        if(tag == 'P')
@@ -358,6 +364,14 @@ static void GPS_A001(GPS_PPacket packet)
                    gps_pvt_transfer = pA800;
                continue;
            }
+           else if (data < 1000)
+           {
+                       /* Stupid Garmin undocumented "A900" packets
+                        * as returned by GPS76, Emap, III, and V in 
+                        * later firmware.
+                        */
+                   continue;
+           }
            else
            {
                GPS_Protocol_Error(tag,data);
@@ -368,7 +382,7 @@ static void GPS_A001(GPS_PPacket packet)
        {
            if(lasta<200)
            {
-               if(data<109 && data>=100)
+               if(data<=109 && data>=100)
                {
                    gps_waypt_type = data;
                    continue;
@@ -401,7 +415,7 @@ static void GPS_A001(GPS_PPacket packet)
                    continue;
                }
                    
-               if(data<109 && data>=100)
+               if(data<=109 && data>=100)
                {
                    gps_rte_type = data;
                    continue;
@@ -446,7 +460,7 @@ static void GPS_A001(GPS_PPacket packet)
 
            else if(lasta<500)
            {
-               if(data<109 && data>=100)
+               if(data<=109 && data>=100)
                {
                    gps_prx_waypt_type = data;
                    continue;
@@ -618,6 +632,9 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way)
        case pD108:
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
+       case pD109:
+           GPS_D109_Get(&((*way)[i]),rec->data);
+           break;
        case pD150:
            GPS_D150_Get(&((*way)[i]),rec->data);
            break;
@@ -737,6 +754,9 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n)
        case pD108:
            GPS_D108_Send(data,way[i],&len);
            break;
+       case pD109:
+           GPS_D109_Send(data,way[i],&len);
+           break;
        case pD150:
            GPS_D150_Send(data,way[i],&len);
            break;
@@ -1169,6 +1189,71 @@ static void GPS_D108_Get(GPS_PWay *way, UC *s)
     return;
 }
 
+/* @funcstatic GPS_D109_Get ********************************************
+**
+** Get waypoint data
+**
+** @param [w] way [GPS_PWay *] waypoint array
+** @param [r] s [UC *] packet data
+**
+** @return [void]
+************************************************************************/
+static void GPS_D109_Get(GPS_PWay *way, UC *s)
+{
+    UC *p;
+    UC *q;
+    
+    int32 i;
+
+    p=s;
+    
+    (*way)->prot = 109;
+    (*way)->wpt_class = *p++;
+    (*way)->colour    = *p++;
+    (*way)->dspl      = *p++;
+    (*way)->attr      = *p++;
+    (*way)->smbl = GPS_Util_Get_Short(p);
+    p+=sizeof(int16);
+    for(i=0;i<18;++i) (*way)->subclass[i] = *p++;
+
+    (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p));
+    p+=sizeof(int32);
+
+    (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p));
+    p+=sizeof(int32);
+    
+    (*way)->alt = (int32)GPS_Util_Get_Float(p);
+    p+=sizeof(float);
+    (*way)->dpth = (int32)GPS_Util_Get_Float(p);
+    p+=sizeof(float);
+    (*way)->dst = (int32)GPS_Util_Get_Float(p);
+    p+=sizeof(float);
+
+    for(i=0;i<2;++i) (*way)->state[i] = *p++;
+    for(i=0;i<2;++i) (*way)->cc[i] = *p++;
+
+    p += 4; /* Skip over "outbound link ete in seconds */
+
+    q = (UC *) (*way)->ident;
+    while((*q++ = *p++));
+    
+    q = (UC *) (*way)->cmnt;
+    while((*q++ = *p++));
+    
+    q = (UC *) (*way)->facility;
+    while((*q++ = *p++));
+    
+    q = (UC *) (*way)->city;
+    while((*q++ = *p++));
+    
+    q = (UC *) (*way)->addr;
+    while((*q++ = *p++));
+    
+    q = (UC *) (*way)->cross_road;
+    while((*q++ = *p++));
+    
+    return;
+}
 
 
 /* @funcstatic GPS_D150_Get ********************************************
@@ -1711,7 +1796,6 @@ static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len)
 
 
 
-
 /* @funcstatic GPS_D108_Send ********************************************
 **
 ** Form waypoint data string
@@ -1773,6 +1857,66 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len)
 }
 
 
+/* @funcstatic GPS_D109_Send ********************************************
+**
+** Form waypoint data string
+**
+** @param [w] data [UC *] string to write to
+** @param [r] way [GPS_PWay] waypoint data
+** @param [w] len [int32 *] packet length
+**
+** @return [void]
+************************************************************************/
+static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len)
+{
+    UC *p;
+    UC *q;
+    
+    int32 i;
+    
+    p = data;
+
+    *p++ = 1; /* D109 constant data (grrrr.) */
+    *p++ = way->wpt_class;
+    *p++ = way->colour;
+    *p++ = way->dspl;
+    *p++ = 0x70;
+    GPS_Util_Put_Short(p,way->smbl);
+    p+=sizeof(int16);
+    for(i=0;i<18;++i) *p++ = way->subclass[i];
+    GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
+    p+=sizeof(int32);
+    GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
+    p+=sizeof(int32);
+
+    GPS_Util_Put_Float(p,way->alt);
+    p+=sizeof(float);
+    GPS_Util_Put_Float(p,way->dpth);
+    p+=sizeof(float);
+    GPS_Util_Put_Float(p,way->dst);
+    p+=sizeof(float);
+
+    for(i=0;i<2;++i) *p++ = way->state[i];
+    for(i=0;i<2;++i) *p++ = way->cc[i];
+    for(i=0;i<4;++i) *p++ = 0xff; /* D109 silliness for ETE */
+
+    q = (UC *) way->ident;
+    while((*p++ = *q++));
+    q = (UC *) way->cmnt;
+    while((*p++ = *q++));
+    q = (UC *) way->facility;
+    while((*p++ = *q++));
+    q = (UC *) way->city;
+    while((*p++ = *q++));
+    q = (UC *) way->addr;
+    while((*p++ = *q++));
+    q = (UC *) way->cross_road;
+    while((*p++ = *q++));
+    
+    *len = p-data;
+    
+    return;
+}
 
 
 /* @funcstatic GPS_D150_Send ********************************************
@@ -3728,6 +3872,9 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way)
        case pD108:
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
+       case pD109:
+           GPS_D109_Get(&((*way)[i]),rec->data);
+           break;
        case pD450:
            GPS_D450_Get(&((*way)[i]),rec->data);
            break;
index 30af011b49ef1f7da1b9c57f4667cb502ea22a8b..ad3e99b6e63a040df3308b2f98eb3e5b5234c067 100644 (file)
@@ -41,6 +41,7 @@ static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf);
+static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf);
 static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf);
@@ -420,6 +421,10 @@ int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf)
            ret = GPS_Input_Get_D108(&((*way)[i]),inf);
            if(ret<0) return gps_errno;
            break;
+       case 109:
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf);
+           if(ret<0) return gps_errno;
+           break;
        case 150:
            ret = GPS_Input_Get_D150(&((*way)[i]),inf);
            if(ret<0) return gps_errno;
@@ -544,6 +549,10 @@ int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf)
            ret = GPS_Input_Get_D108(&((*way)[i]),inf);
            if(ret<0) return gps_errno;
            break;
+       case 109:
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf);
+           if(ret<0) return gps_errno;
+           break;
        case 450:
            ret = GPS_Input_Get_D150(&((*way)[i]),inf);
            if(ret<0) return gps_errno;
@@ -1053,6 +1062,143 @@ static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf)
 
 
 
+/* @funcstatic GPS_Input_Get_D109   ************************************
+**
+** Get a D109 Entry
+**
+** @param [w] way [GPS_PWay *] pointer to waypoint entry
+** @param [r] inf [FILE *] stream
+**
+** @return [int32] number of entries
+************************************************************************/
+static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf)
+{
+    char s[GPS_ARB_LEN];
+    char *p;
+    double f;
+    int32 d;
+    int32 xc;
+    
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    GPS_Input_Load_Strnull((*way)->ident,s);
+    
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%lf",&f)!=1)
+           return gps_errno;
+    (*way)->lat = f;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%lf",&f)!=1)
+           return gps_errno;
+    (*way)->lon = f;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%d",(int *)&d)!=1)
+           return gps_errno;
+    (*way)->colour = d;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%d",(int *)&d)!=1)
+           return gps_errno;
+    (*way)->dspl = d;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%d",(int *)&d)!=1)
+           return gps_errno;
+    (*way)->smbl = d;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%d",(int *)&d)!=1)
+           return gps_errno;
+    (*way)->alt = d;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%lf",&f)!=1)
+           return gps_errno;
+    (*way)->dpth = f;
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    GPS_Input_Load_String((*way)->state,2,s);
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    GPS_Input_Load_String((*way)->cc,2,s);
+
+    if(!GPS_Input_Read_Line(s,inf))
+       return gps_errno;
+    p=strchr(s,':');
+    if(sscanf(p+1,"%d",(int *)&d)!=1)
+           return gps_errno;
+    (*way)->wpt_class = d;
+    xc = d;
+
+    if(xc>=0x80 && xc<=0x85)
+    {
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_String((char *)(*way)->subclass,18,s);
+    }
+    else
+    {
+       GPS_Util_Put_Short((*way)->subclass,0);
+       GPS_Util_Put_Int((*way)->subclass+2,0);
+       GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff);
+       GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff);
+       GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff);
+    }
+       
+    if(!xc)
+    {
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_Strnull((*way)->cmnt,s);
+    }
+
+    if(xc>=0x40 && xc<=0x46)
+    {
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_Strnull((*way)->facility,s);
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_Strnull((*way)->city,s);
+    }
+
+    if(xc==0x83)
+    {
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_Strnull((*way)->addr,s);
+    }
+
+    if(xc==0x82)
+    {
+       if(!GPS_Input_Read_Line(s,inf))
+           return gps_errno;
+       GPS_Input_Load_Strnull((*way)->cross_road,s);
+    }
+
+    return 1;
+}
+
+
 /* @funcstatic GPS_Input_Get_D150   ************************************
 **
 ** Get a D150 Entry
index af78b55f45a22fa58edcce83e97ab2b410e41a2b..ff8adf95c19c04e3ced683f8d0e6fd797e915495 100644 (file)
@@ -139,6 +139,7 @@ int32 gps_pvt_transfer;
 #define pD106 106
 #define pD107 107
 #define pD108 108
+#define pD109 109
 #define pD150 150
 #define pD151 151
 #define pD152 152